/* 2019/7/25 接口协议
1. 获取全部/当前菜单基本信息:
		get url=http://127.0.0.1:9001/queryMenu?cmd=all/current
		get url=http://127.0.0.1:9001/queryMenu?cmd=current&menuname=全菜单
设置当前菜单时，将当前菜单名存储到本地，每次加载时，机器人读取本地存储的当前菜单名，然后跟据菜单名请求菜单内容。为满足不同档口分开使用菜单的需求.
	返回：
	{
	  Cmd: "queryMenuAll/queryMenucurrent",
	  FoodInfos: [
	    {
	      Name: "菜花炒肉",
	      Price: 500,
	      OtherName: "菜花炒肉"
	    },
	    {
	      Name: "菠罗包",
	      Price: 400,
	      OtherName: "菠罗包"
	    }
	  ]
	}
2. 根据菜名获取该菜品所有的信息，包括图片url和特征:get url=/queryFoodInfo?name=包子
	{
		Cmd: "queryFoodInfo",
		Name: "包子",
		FoodImagesUrl :[ "/包子1.jpg", "/包子2.jpg" ]
		FoodFeatures:[ "dsadfsadfsadfsadf", "sdfsdfoiuoiuoio" ] //base64编码
	}
	根据菜名获取该菜品的所有图片信息，get url=/queryFoodImgUrl?name=包子
	{
		Cmd: "queryFoodImgUrl",
		Name: "包子",
		FoodImagesUrl :[ "/包子1.jpg", "/包子2.jpg" ]
	}
3. 加菜/追加菜：post url=/addFoodInfo
	{
		Cmd: "addFoodInfo",
		Name: "包子",
		//OtherName: "包子",
		Price: 500,
		Mac: "mac",
		ImageData: "base64",
		FeatureData: "base64",
		BoxCoord: "x1&y1&x2&y2"
	}
	{
		Cmd: "addFoodInfo",
		Result: "ok/fail",
		Desc:""
	}
4. 删菜：get url=/delFoodInfo?name=包子
	{
		Cmd: "delFoodInfo",
		Result: "ok/fail",
		Desc:""
	}
5. 修改菜品价格/别名：post url=/editFoodInfo
	{
		Cmd: "editFoodInfo",
		Name: "包子",
		OtherName: "da包子",
		Price: 500
	}
	{
		Cmd: "editFoodInfo",
		Result: "ok/fail",
		Desc:""
	}
6. 删除固定的特征文件: post url=/delFixFoodFea
	{
		Cmd: "delFixFoodFea",
		FeaName: "包子_mac_20190730104711_x1&y1&x2&y2"
	}
7. 心跳: get url=/syncHeartBeat
	//维护一个同步任务队列，对同步的任务做短期记忆：文件夹作为队列使用，一个个任务即一个个文件，任务内容存储在文件中，使用文件名来记录一些基本信息
	// 时间戳_UUID_ip1_ip2_ipn.syn //中间文件 没有.syn 防止写时还未写完 就被多个地方读，等写完后再重命名。读取文件中的内容作为回复的Json结构体
	//addFoodInfo: { Cmd:"syncHeartBeat", "TaskId":"addFoodInfo", "Name":"包子", "Price":500, "Feature":"base64" }
	//delFoodInfo: { Cmd:"syncHeartBeat", "TaskId":"delFoodInfo", "Name":"包子" }
	//delFixFoodFea: { Cmd:"syncHeartBeat", "TaskId":"delFixFoodFea", "Name":"包子" } 清楚这个菜的所有特征，然后重新获取这个菜的所有特征并进行注册
	//editFoodInfo: { Cmd:"syncHeartBeat", "TaskId":"editFoodInfo", "Name":"包子", "Price":800, "OtherName":"狗蛋包" }
	//ok: { Cmd:"syncHeartBeat", "TaskId":"ok" }
	//StartupDelaySync: { Cmd:"syncHeartBeat", "TaskId":"StartupDelaySync" } 创建开机延迟同步文件
	//editMenuContent: { Cmd:"syncHeartBeat", "TaskId":"editMenuContent", "MenuName":"北大农园6.25" } 每当菜单内容改变时，需要创建同步任务队列，每个客户端通过心跳，自检测需不需要更新此菜单的全部

8. 能量：get url=/queryFoodEnergy?name=包子,饺子
	{
		Cmd: "queryFoodEnergy",
		Foods:[
			{
				Name: "包子",
				Hot: "500",
				Sugar:"111",
				Fat:"22",
				Protein:"33"
			},
			{
				Name: "饺子",
				Hot: "500",
				Sugar:"111",
				Fat:"22",
				Protein:"33"
			},
		]
	}
9. 能量：post url/editFoodEnergy
	{
		Cmd: "editFoodEnergy",
		Name: "包子",
		Hot: "500",
		Sugar:"111",
		Fat:"22",
		Protein:"33"
	}
10. 获取所有菜单：get url/queryAllMenus
	{
		Cmd:"queryAllMenus",
		//CurUseMenu:"原始菜单/菜单名", // //弃用，改由机器人本地存储当前使用的菜单名
		Menus :[ "北大农园6.25", "北大农园0627", "北大农园七月固定" ]
	}
11. 查询菜单内容根据菜单名：get url/queryMenuInfo?name=北大农园6.25
	{
		Cmd:"queryMenuInfo",
		MenuName:"北大农园6.25",
		FoodNames :[ "一两米饭", "三两米饭", "三角蛋糕" ]
		AllFoodNames:[]
	}
12. 设置为当前使用的菜：get url/setCurrentMenu?name=北大农园6.25     //弃用，改由机器人本地存储当前使用的菜单名
	{
		Cmd:"setCurrentMenu",
		MenuName:"北大农园6.25"
	}
13. 删除菜单根据菜单名: get url/delMeun?name=北大农园6.25
	{
		Cmd:"delMeun",
		MenuName:"北大农园6.25"
	}
14. 更新菜单中的内容，没有则创建，有则更新 post url/editMenuContent
	{
		Cmd:"editMenuContent",
		MenuName:"北大农园6.25",
		FoodNames :[ "一两米饭", "三两米饭", "三角蛋糕" ]
	}
	{
		Cmd:"editMenuContent",
		MenuName:"北大农园6.25"
	}

*/
package main

import (
	"bufio"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"gLogService/common"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"
	"unicode/utf8"
)

type FoodInfo struct {
	Name      string
	Price     int
	OtherName string
}

type FoodInfoSlice struct {
	Cmd       string
	FoodInfos []FoodInfo
}

type FoodDetailsSlice struct {
	Cmd           string
	Name          string
	FoodImagesUrl []string
	FoodFeatures  []string
}

type QueryAllMenu struct {
	Cmd string
	// CurUseMenu string
	Menus []string
}

type QueryMenuInfo struct {
	Cmd          string
	MenuName     string
	FoodNames    []string
	AllFoodNames []string
}

type FoodNutrition struct {
	Name    string
	Hot     string
	Sugar   string
	Fat     string
	Protein string
}

type FoodsNutritionData struct {
	Cmd   string
	Foods []FoodNutrition
}

func queryMenu(w http.ResponseWriter, r *http.Request) {
	cmd := r.FormValue("cmd")

	fmt.Println("queryMenu, CurrentUseMenuName=", r.FormValue("menuname"))

	if "all" == cmd {
		//获取全菜单基本信息
		var slist []string
		slist, _ = common.GetFolderFilesNameBaseonFood(FoodInfoPath, slist)
		var AllFoods FoodInfoSlice
		AllFoods.Cmd = "queryMenuAll"
		for index := range slist {
			strArr := strings.Split(slist[index], "-")
			// fmt.Printf("%s-%s-%s \n", strArr[0], strArr[1], strArr[2])
			nPrice, _ := strconv.Atoi(strArr[1])
			AllFoods.FoodInfos = append(AllFoods.FoodInfos, FoodInfo{Name: strArr[0], Price: nPrice, OtherName: strArr[2]})
		}
		allFoodsInfo, _ := json.Marshal(AllFoods)
		w.Header().Set("Content-Type", "application/json;charset=UTF-8")
		w.Write(allFoodsInfo)
	} else if "current" == cmd {
		//获取当前菜单基本信息
		CurrentUseMenuName := r.FormValue("menuname")
		//0.确定当前菜单名称
		var AllFoods FoodInfoSlice
		AllFoods.Cmd = "queryMenucurrent"
		//1.获取全菜单
		var slist []string
		slist, _ = common.GetFolderFilesNameBaseonFood(FoodInfoPath, slist)
		//2.判断是否是全菜单，如果是全菜单，则直接组装
		if "全菜单" == CurrentUseMenuName {
			for index := range slist {
				// slist[index] = 菜花炒肉-500-菜花炒肉
				strArr := strings.Split(slist[index], "-")
				nPrice, _ := strconv.Atoi(strArr[1])
				AllFoods.FoodInfos = append(AllFoods.FoodInfos, FoodInfo{Name: strArr[0], Price: nPrice, OtherName: strArr[2]})
			}
		} else {
			//3. 获取当前菜单所有菜名，并根据全菜单生成当前菜单的基本信息
			mapallFoodInfos := make(map[string]string)
			for index := range slist {
				// slist[index] = 菜花炒肉-500-菜花炒肉
				strArr := strings.Split(slist[index], "-")
				mapallFoodInfos[strArr[0]] = slist[index]
			}
			curMenuFilePath := filepath.Join(FoodMenuDir, CurrentUseMenuName+".json")
			data2, _ := ioutil.ReadFile(curMenuFilePath)
			var curMenuFoodNames []string
			json.Unmarshal(data2, &curMenuFoodNames)
			for index := range curMenuFoodNames {
				infos := mapallFoodInfos[curMenuFoodNames[index]]
				if strings.Count(infos, "")-1 > 1 {
					strArr := strings.Split(infos, "-")
					nPrice, _ := strconv.Atoi(strArr[1])
					AllFoods.FoodInfos = append(AllFoods.FoodInfos, FoodInfo{Name: strArr[0], Price: nPrice, OtherName: strArr[2]})
				}
			}
		}
		allFoodsInfo, _ := json.Marshal(AllFoods)
		w.Header().Set("Content-Type", "application/json;charset=UTF-8")
		w.Write(allFoodsInfo)
	} else {
		//其他
	}
}

func queryFoodInfo(w http.ResponseWriter, r *http.Request) {
	name := r.FormValue("name")
	foodFeatureDir := filepath.Join(FoodFeaturePath, name)
	var sJpgFea []string
	sJpgFea, _ = common.GetFolderFilesNameBaseonJPGFea(foodFeatureDir, sJpgFea)
	var foodDetails FoodDetailsSlice
	foodDetails.Cmd = "queryFoodInfo"
	foodDetails.Name = name
	for index := range sJpgFea {
		var builder strings.Builder
		builder.WriteString("/foodImage/")
		builder.Write([]byte(sJpgFea[index]))
		builder.WriteString(".jpg")
		foodDetails.FoodImagesUrl = append(foodDetails.FoodImagesUrl, builder.String())
		var feaPathFile strings.Builder
		feaPathFile.WriteString(FoodFeaturePath)
		feaPathFile.WriteByte('/')
		feaPathFile.WriteString(name)
		feaPathFile.WriteByte('/')
		feaPathFile.WriteString(sJpgFea[index])
		feaPathFile.WriteString(".fea")
		feadata, _ := ioutil.ReadFile(feaPathFile.String())
		foodDetails.FoodFeatures = append(foodDetails.FoodFeatures, base64.StdEncoding.EncodeToString(feadata))
	}
	detailsJson, _ := json.Marshal(foodDetails)
	w.Header().Set("Content-Type", "application/json;charset=UTF-8")
	w.Write(detailsJson)
}

// 根据菜名获取该菜品的所有图片信息，get url=/queryFoodImgUrl?name=包子
// {
// 	Cmd: "queryFoodImgUrl",
// 	Name: "包子",
// 	FoodImagesUrl :[ "/foodImage/包子_00044bc77ae0_20190716104215_1013&254&1381&579.jpg",
// 					"/foodImage/包子_00044bc77ae0_20190718164601_1404&1028&1721&1361.jpg" ]
// }
func queryFoodImgUrl(w http.ResponseWriter, r *http.Request) {
	name := r.FormValue("name")
	foodFeatureDir := filepath.Join(FoodFeaturePath, name)
	var sJpgFea []string
	sJpgFea, _ = common.GetFolderFilesNameBaseonJPGFea(foodFeatureDir, sJpgFea)
	var foodDetails FoodDetailsSlice
	foodDetails.Cmd = "queryFoodImgUrl"
	foodDetails.Name = name
	for index := range sJpgFea {
		var builder strings.Builder
		builder.WriteString("/foodImage/")
		builder.Write([]byte(sJpgFea[index]))
		builder.WriteString(".jpg")
		foodDetails.FoodImagesUrl = append(foodDetails.FoodImagesUrl, builder.String())
	}
	detailsJson, _ := json.Marshal(foodDetails)
	w.Header().Set("Content-Type", "application/json;charset=UTF-8")
	w.Write(detailsJson)
}

func addFoodInfo(w http.ResponseWriter, r *http.Request) {
	body, _ := ioutil.ReadAll(r.Body)
	var dat map[string]interface{}
	resultmap := make(map[string]interface{})
	if err := json.Unmarshal(body, &dat); err == nil {
		Judge_FoodFeatureDir := filepath.Join(FoodFeaturePath, dat["Name"].(string))
		IsExist, _ := common.PathExists(Judge_FoodFeatureDir)
		if !IsExist {
			os.MkdirAll(Judge_FoodFeatureDir, os.ModePerm)
		}
		// 创建/foodInfo/包子-500-包子.food-----如果foodInfo中已经存在 以 Name 为首的命名，则需要更改其价格，仅需要更改其价格
		ExistStr := common.GetFoodInfoFolderName(FoodInfoPath, dat["Name"].(string))
		if "" == ExistStr {
			//菜品不存在则创建
			foodInfoPathFile := fmt.Sprintf("%s/%s-%0.0f-%s.food", FoodInfoPath, dat["Name"].(string), dat["Price"].(float64), dat["Name"].(string))
			f, _ := os.Create(foodInfoPathFile)
			defer f.Close()
		} else {
			tmpSplit := strings.Split(ExistStr, "-")
			NewfoodInfoPathFile := fmt.Sprintf("%s/%s-%0.0f-%s.food", FoodInfoPath, tmpSplit[0], dat["Price"].(float64), tmpSplit[2])
			OldfoodInfoPathFile := fmt.Sprintf("%s/%s.food", FoodInfoPath, ExistStr)
			os.Rename(OldfoodInfoPathFile, NewfoodInfoPathFile)
		}
		// 创建jpg/fea文件
		t := time.Now()
		curTime := fmt.Sprintf("%d%02d%02d%02d%02d%02d", t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second())
		newImgPathName := fmt.Sprintf("%s/%s_%s_%s_%s.jpg", Judge_FoodFeatureDir, dat["Name"].(string), dat["Mac"].(string), curTime, dat["BoxCoord"].(string))
		newFeaPathName := fmt.Sprintf("%s/%s_%s_%s_%s.fea", Judge_FoodFeatureDir, dat["Name"].(string), dat["Mac"].(string), curTime, dat["BoxCoord"].(string))
		fileImg, _ := os.OpenFile(newImgPathName, os.O_WRONLY|os.O_CREATE, 0666)
		defer fileImg.Close()
		imgdata, _ := base64.StdEncoding.DecodeString(dat["ImageData"].(string))
		fileImg.Write(imgdata)

		fileFea, _ := os.OpenFile(newFeaPathName, os.O_WRONLY|os.O_CREATE, 0666)
		defer fileFea.Close()
		feadata, _ := base64.StdEncoding.DecodeString(dat["FeatureData"].(string))
		fileFea.Write(feadata)

		// 创建同步文件
		// addFoodInfo: { Cmd:"syncHeartBeat", "TaskId":"addFoodInfo", "Name":"包子", "Price": 500, "Feature":"base64" }
		UUID++
		sync_AddFoodInfoFile := fmt.Sprintf("%s/%d_%d.syn", TaskIdList, time.Now().Unix(), UUID)
		syncAddFoodMap := make(map[string]interface{})
		syncAddFoodMap["Cmd"] = "syncHeartBeat"
		syncAddFoodMap["TaskId"] = "addFoodInfo"
		syncAddFoodMap["Name"] = dat["Name"]
		syncAddFoodMap["Price"] = dat["Price"].(float64)
		syncAddFoodMap["Feature"] = dat["FeatureData"]
		fileSyncFea, _ := os.OpenFile(sync_AddFoodInfoFile, os.O_WRONLY|os.O_CREATE, 0666)
		defer fileSyncFea.Close()
		syncFeaData, _ := json.Marshal(syncAddFoodMap)
		fileSyncFea.Write(syncFeaData)

		//
		resultmap["Result"] = "ok"
		resultmap["Desc"] = "加菜/追加成功"
	} else {
		resultmap["Result"] = "fail"
		resultmap["Desc"] = "json array"
	}
	resultmap["Cmd"] = "addFoodInfo"
	sendResult, _ := json.Marshal(resultmap)
	w.Header().Set("Content-Type", "application/json;charset=UTF-8")
	w.Write(sendResult)
}

func delFoodInfo(w http.ResponseWriter, r *http.Request) {
	name := r.FormValue("name")
	//1. 删除菜品文件：根据菜名找到 包子-500-包子.food 并删掉
	fullName, _ := common.GetFilePathBaseonName(FoodInfoPath, name)
	os.Remove(filepath.Join(FoodInfoPath, fullName))
	//2. 删除菜品特征文件：根据菜名找到 /foodfeature/包子 并清空文件夹
	common.RemoveAllContents(filepath.Join(FoodFeaturePath, name))

	//3. 创建同步文件
	// delFoodInfo: { Cmd:"syncHeartBeat", "TaskId":"delFoodInfo", "Name":"包子" }
	UUID++
	sync_DelFoodInfoFile := fmt.Sprintf("%s/%d_%d.syn", TaskIdList, time.Now().Unix(), UUID)
	syncDelFoodMap := make(map[string]interface{})
	syncDelFoodMap["Cmd"] = "syncHeartBeat"
	syncDelFoodMap["TaskId"] = "delFoodInfo"
	syncDelFoodMap["Name"] = name
	fileSyncFea, _ := os.OpenFile(sync_DelFoodInfoFile, os.O_WRONLY|os.O_CREATE, 0666)
	defer fileSyncFea.Close()
	syncFeaData, _ := json.Marshal(syncDelFoodMap)
	fileSyncFea.Write(syncFeaData)

	//
	resultmap := make(map[string]interface{})
	resultmap["Cmd"] = "delFoodInfo"
	resultmap["Result"] = "ok"
	sendResult, _ := json.Marshal(resultmap)
	w.Header().Set("Content-Type", "application/json;charset=UTF-8")
	w.Write(sendResult)
}

func delFixFoodFea(w http.ResponseWriter, r *http.Request) {
	body, _ := ioutil.ReadAll(r.Body)
	var dat map[string]interface{}
	json.Unmarshal(body, &dat)
	feaName := dat["FeaName"].(string)

	//包子_mac_20190730104711_x1&y1&x2&y2
	foodName := strings.Split(feaName, "_")[0]
	JpgPathFile := fmt.Sprintf("%s/%s/%s.jpg", FoodFeaturePath, foodName, feaName)
	FeaPathFile := fmt.Sprintf("%s/%s/%s.fea", FoodFeaturePath, foodName, feaName)

	os.Remove(JpgPathFile)
	os.Remove(FeaPathFile)

	// 创建同步文件
	// delFixFoodFea: { Cmd:"syncHeartBeat", "TaskId":"delFixFoodFea", "Name":"包子" } 清楚这个菜的所有特征，然后重新获取这个菜的所有特征并进行注册
	UUID++
	sync_DelFoodFeaFile := fmt.Sprintf("%s/%d_%d.syn", TaskIdList, time.Now().Unix(), UUID)
	syncDelFoodMap := make(map[string]interface{})
	syncDelFoodMap["Cmd"] = "syncHeartBeat"
	syncDelFoodMap["TaskId"] = "delFixFoodFea"
	syncDelFoodMap["Name"] = foodName
	fileSyncFea, _ := os.OpenFile(sync_DelFoodFeaFile, os.O_WRONLY|os.O_CREATE, 0666)
	defer fileSyncFea.Close()
	syncFeaData, _ := json.Marshal(syncDelFoodMap)
	fileSyncFea.Write(syncFeaData)

	//
	resultmap := make(map[string]interface{})
	resultmap["Cmd"] = "delFixFoodFea"
	resultmap["Result"] = "ok"
	sendResult, _ := json.Marshal(resultmap)
	w.Header().Set("Content-Type", "application/json;charset=UTF-8")
	w.Write(sendResult)
}

func editFoodInfo(w http.ResponseWriter, r *http.Request) {
	body, _ := ioutil.ReadAll(r.Body)
	var dat map[string]interface{}
	resultmap := make(map[string]interface{})
	if err := json.Unmarshal(body, &dat); err == nil {
		fullName, _ := common.GetFilePathBaseonName(FoodInfoPath, dat["Name"].(string))
		newFullName := fmt.Sprintf("%s-%0.0f-%s.food", dat["Name"].(string), dat["Price"].(float64), dat["OtherName"].(string))
		os.Rename(filepath.Join(FoodInfoPath, fullName), filepath.Join(FoodInfoPath, newFullName))
	}

	// 创建同步文件
	// editFoodInfo: { Cmd:"syncHeartBeat", "TaskId":"editFoodInfo", "Name":"包子", "Price":800, "OtherName":"狗蛋包" }
	UUID++
	sync_EditFoodFeaFile := fmt.Sprintf("%s/%d_%d.syn", TaskIdList, time.Now().Unix(), UUID)
	syncEditFoodMap := make(map[string]interface{})
	syncEditFoodMap["Cmd"] = "syncHeartBeat"
	syncEditFoodMap["TaskId"] = "editFoodInfo"
	syncEditFoodMap["Name"] = dat["Name"].(string)
	syncEditFoodMap["Price"] = dat["Price"].(float64)
	syncEditFoodMap["OtherName"] = dat["OtherName"].(string)
	fileSyncFea, _ := os.OpenFile(sync_EditFoodFeaFile, os.O_WRONLY|os.O_CREATE, 0666)
	defer fileSyncFea.Close()
	syncFeaData, _ := json.Marshal(syncEditFoodMap)
	fileSyncFea.Write(syncFeaData)
	//
	resultmap["Cmd"] = "editFoodInfo"
	resultmap["Result"] = "ok"
	sendResult, _ := json.Marshal(resultmap)
	w.Header().Set("Content-Type", "application/json;charset=UTF-8")
	w.Write(sendResult)
}

func foodImageShow(w http.ResponseWriter, r *http.Request) {
	urlPath := r.URL.Path
	// url = /foodImage/包子_00044bc77ae0_20190716104215_1013&254&1381&579.jpg
	if utf8.RuneCountInString("/foodImage/") < utf8.RuneCountInString(urlPath) {
		_, fileName := filepath.Split(urlPath)
		// c:/abs/adytum/foodfeature/包子/包子_20190424165512_58.jpg
		urlExport := filepath.Join(FoodFeaturePath, strings.Split(fileName, "_")[0], fileName)
		http.ServeFile(w, r, urlExport)
	} else {
		fmt.Println(utf8.RuneCountInString(urlPath))
	}
}

//维护一个同步任务队列，对同步的任务做短期记忆：文件夹作为队列使用，一个个任务即一个个文件，任务内容存储在文件中，使用文件名来记录一些基本信息
//时间戳_UUID_ip1_ip2_ipn.syn
func syncHeartBeat(w http.ResponseWriter, r *http.Request) {
	var haveSendData []byte
	var taskList []string
	bIsSend := false
	taskList, _ = common.GetFolderFilesNameBaseonSyn(TaskIdList, taskList)
	for index := range taskList {
		allpathfile := filepath.Join(TaskIdList, taskList[index])
		startTmpTime := strings.Split(taskList[index], "_")[0]
		startTime, _ := strconv.ParseInt(startTmpTime, 10, 64)
		if (time.Now().Unix() - startTime) > 60*30 {
			//做短期记忆
			os.Remove(allpathfile)
		} else {
			//判断此消息是否被请求对象请求过，如果没被请求过，则发送
			remoteAddr := strings.Split(strings.Replace(r.RemoteAddr, ".", "", -1), ":")[0]

			ComparIp := strings.Split(taskList[index], ".")[0] // 时间戳_UUID_ip1_ip2_ipn.syn -->时间戳_UUID_ip1_ip2_ipn
			stringList := strings.Split(ComparIp, "_")
			bIsHaveRemoteAddr := false
			for i := 2; i < len(stringList); i++ {
				if remoteAddr == stringList[i] {
					bIsHaveRemoteAddr = true
					break
				}
			}
			if !bIsHaveRemoteAddr {
				bIsSend = true
				haveSendData, _ = ioutil.ReadFile(allpathfile)

				tmpName := strings.Split(taskList[index], ".")[0]
				newFileName := fmt.Sprintf("%s/%s_%s.syn", TaskIdList, tmpName, remoteAddr)
				os.Rename(allpathfile, newFileName)
				break
			}
		}
	}
	if bIsSend {
		w.Header().Set("Content-Type", "application/json;charset=UTF-8")
		w.Write(haveSendData)
	} else {
		resultmap := make(map[string]interface{})
		resultmap["Cmd"] = "syncHeartBeat"
		resultmap["TaskId"] = "ok"
		sendResult, _ := json.Marshal(resultmap)
		w.Header().Set("Content-Type", "application/json;charset=UTF-8")
		w.Write(sendResult)
	}
}

func queryFoodEnergy(w http.ResponseWriter, r *http.Request) {
	name := r.FormValue("name")
	namelist := strings.Split(name, ",")

	var FoodsData FoodsNutritionData

	if fi, err := os.Open(NutritionFile); err == nil {
		defer fi.Close()

		br := bufio.NewReader(fi)
		for {
			a, _, c := br.ReadLine()
			if c == io.EOF {
				break
			}

			parts := strings.Split(string(a), "-")

			for i := 0; i < len(namelist); i++ {
				foodName := namelist[i]
				if foodName == parts[0] {
					FoodsData.Foods = append(FoodsData.Foods, FoodNutrition{Name: foodName, Hot: parts[1], Sugar: parts[2], Fat: parts[3], Protein: parts[4]})
				}
			}
		}
	}
	FoodsData.Cmd = "queryFoodEnergy"
	sendResult, _ := json.Marshal(FoodsData)
	w.Header().Set("Content-Type", "application/json;charset=UTF-8")
	w.Write(sendResult)
}

func editFoodEnergy(w http.ResponseWriter, r *http.Request) {
	body, _ := ioutil.ReadAll(r.Body)
	bIsHave := false
	var builder strings.Builder
	var dat map[string]interface{}
	if err := json.Unmarshal(body, &dat); err == nil {
		if fi, err := os.OpenFile(NutritionFile, os.O_RDWR, 0666); err == nil {
			defer fi.Close()

			name := dat["Name"].(string)

			br := bufio.NewReader(fi)
			for {
				a, _, c := br.ReadLine()
				if c == io.EOF {
					break
				}
				strLine := string(a)
				parts := strings.Split(strLine, "-")
				if name == parts[0] {
					bIsHave = true
					strLine = fmt.Sprintf("%s-%s-%s-%s-%s", name, dat["Hot"].(string), dat["Sugar"].(string), dat["Fat"].(string), dat["Protein"].(string))
				}
				builder.WriteString(strLine)
				builder.WriteByte('\n')
			}

			if !bIsHave {
				strLine := fmt.Sprintf("%s-%s-%s-%s-%s", name, dat["Hot"].(string), dat["Sugar"].(string), dat["Fat"].(string), dat["Protein"].(string))
				builder.WriteString(strLine)
			}
			fi.Truncate(0)
			fi.Seek(0, 0)
			fi.WriteString(builder.String())
		}
	}

	resultmap := make(map[string]interface{})
	resultmap["Cmd"] = "editFoodEnergy"
	resultmap["Result"] = "ok"
	sendResult, _ := json.Marshal(resultmap)
	w.Header().Set("Content-Type", "application/json;charset=UTF-8")
	w.Write(sendResult)
}

func queryAllMenus(w http.ResponseWriter, r *http.Request) {
	var querymenu QueryAllMenu
	querymenu.Cmd = "queryAllMenus"
	querymenu.Menus, _ = common.GetAllMenusName(FoodMenuDir, querymenu.Menus)
	// sync_cfgFile := filepath.Join(CurExeUpperDir, "adytum", "sync_cfg.json")
	// sync_cfgData, _ := ioutil.ReadFile(sync_cfgFile)

	// var dat map[string]interface{}
	// if err := json.Unmarshal(sync_cfgData, &dat); err == nil {
	// 	querymenu.CurUseMenu = dat["current_menu"].(string)
	// }
	sendResult, _ := json.Marshal(querymenu)
	w.Header().Set("Content-Type", "application/json;charset=UTF-8")
	w.Write(sendResult)
}

func queryMenuInfo(w http.ResponseWriter, r *http.Request) {
	name := r.FormValue("name")
	var slist []string
	foodNames, _ := common.GetfullMenuFoods(FoodInfoPath, slist)
	var querymenuInfo QueryMenuInfo
	querymenuInfo.AllFoodNames = foodNames
	if "全菜单" == name {
		querymenuInfo.FoodNames = foodNames
	} else {
		menuInfoFileName := filepath.Join(FoodMenuDir, name+".json")
		data, _ := ioutil.ReadFile(menuInfoFileName)
		json.Unmarshal(data, &querymenuInfo.FoodNames)
	}

	querymenuInfo.Cmd = "queryMenuInfo"
	querymenuInfo.MenuName = name
	sendResult, _ := json.Marshal(querymenuInfo)
	w.Header().Set("Content-Type", "application/json;charset=UTF-8")
	w.Write(sendResult)
}

func setCurrentMenu(w http.ResponseWriter, r *http.Request) {
	// name := r.FormValue("name")

	// sync_cfgFile := filepath.Join(CurExeUpperDir, "adytum", "sync_cfg.json")
	// sync_cfgData, _ := ioutil.ReadFile(sync_cfgFile)
	// var dat map[string]interface{}
	// if err := json.Unmarshal(sync_cfgData, &dat); err == nil {
	// 	dat["current_menu"] = name
	// 	data, _ := json.Marshal(dat)

	// 	if fi, err := os.OpenFile(sync_cfgFile, os.O_RDWR, 0666); err == nil {
	// 		defer fi.Close()

	// 		fi.Truncate(0)
	// 		fi.Seek(0, 0)
	// 		fi.Write(data)
	// 	}
	// }

	// resultmap := make(map[string]interface{})
	// resultmap["Cmd"] = "setCurrentMenu"
	// resultmap["CurrentMenuName"] = name
	// sendResult, _ := json.Marshal(resultmap)
	// w.Header().Set("Content-Type", "application/json;charset=UTF-8")
	// w.Write(sendResult)
}

func delMeun(w http.ResponseWriter, r *http.Request) {
	name := r.FormValue("name")

	menuInfoFileName := filepath.Join(FoodMenuDir, name+".json")
	os.Remove(menuInfoFileName)

	resultmap := make(map[string]interface{})
	resultmap["Cmd"] = "delMeun"
	resultmap["MenuName"] = name
	sendResult, _ := json.Marshal(resultmap)
	w.Header().Set("Content-Type", "application/json;charset=UTF-8")
	w.Write(sendResult)
}

// 更新菜单中的内容，没有则创建，有则更新 post url/editMenuContent
// 	{
// 		Cmd:"editMenuContent",
// 		MenuName:"北大农园6.25",
// 		FoodNames :[ "一两米饭", "三两米饭", "三角蛋糕" ]
// 	}
// 	{
// 		Cmd:"editMenuContent",
// 		MenuName:"北大农园6.25"
// 	}
//editMenuContent: { Cmd:"syncHeartBeat", "TaskId":"editMenuContent", "MenuName":"北大农园6.25" } 每当菜单内容改变时，需要创建同步任务队列，每个客户端通过心跳，自检测需不需要更新此菜单的全部
func editMenuContent(w http.ResponseWriter, r *http.Request) {
	body, _ := ioutil.ReadAll(r.Body)
	menuName := ""
	var dat map[string]interface{}
	if err := json.Unmarshal(body, &dat); err == nil {
		menuName = dat["MenuName"].(string)

		dataSave, _ := json.Marshal(dat["FoodNames"])

		menuInfoFileName := filepath.Join(FoodMenuDir, menuName+".json")
		if fi, err := os.OpenFile(menuInfoFileName, os.O_RDWR|os.O_CREATE, 0666); err == nil {
			defer fi.Close()
			fi.Truncate(0)
			fi.Seek(0, 0)
			fi.Write(dataSave)
		} else {
			fmt.Println(menuInfoFileName, err)
		}

		// 创建同步文件
		// editMenuContent: { Cmd:"syncHeartBeat", "TaskId":"editMenuContent", "MenuName":"北大农园6.25" }
		UUID++
		sync_EditMenuContentFile := fmt.Sprintf("%s/%d_%d.syn", TaskIdList, time.Now().Unix(), UUID)
		syncEditMenuContentMap := make(map[string]interface{})
		syncEditMenuContentMap["Cmd"] = "syncHeartBeat"
		syncEditMenuContentMap["TaskId"] = "editMenuContent"
		syncEditMenuContentMap["MenuName"] = menuName
		fileSyncFea, _ := os.OpenFile(sync_EditMenuContentFile, os.O_WRONLY|os.O_CREATE, 0666)
		defer fileSyncFea.Close()
		syncData, _ := json.Marshal(syncEditMenuContentMap)
		fileSyncFea.Write(syncData)
	}
	resultmap := make(map[string]interface{})
	resultmap["Cmd"] = "editMenuContent"
	resultmap["MenuName"] = menuName
	sendResult, _ := json.Marshal(resultmap)
	w.Header().Set("Content-Type", "application/json;charset=UTF-8")
	w.Write(sendResult)
}

/* 当一台机器人中新增菜后，需要加入到这台机器人的当前使用的菜单中
收到此消息后，根据菜单名找到此菜单，判断此菜是否在当前菜单中，如果在，则返回，如果不在，则需要添加后返回.
{
	Cmd:"autoAddCurrentMenu",
	MenuName:"星期一",
	FoodName:"一两米饭"
}
*/

func autoAddCurrentMenu(w http.ResponseWriter, r *http.Request) {
	body, _ := ioutil.ReadAll(r.Body)
	var dat map[string]interface{}
	reply := make(map[string]interface{})
	if err := json.Unmarshal(body, &dat); err == nil {
		menuName := dat["MenuName"].(string)
		menuInfoFileName := filepath.Join(FoodMenuDir, menuName+".json")
		dataInfo, _ := ioutil.ReadFile(menuInfoFileName)
		var FoodNameList []string
		json.Unmarshal(dataInfo, &FoodNameList)
		bExit := false
		for index := range FoodNameList {
			if dat["FoodName"] == FoodNameList[index] {
				bExit = true
			}
		}
		if bExit {
		} else {
			FoodNameList = append(FoodNameList, dat["FoodName"].(string))
			dataSave, _ := json.Marshal(FoodNameList)
			if fi, err := os.OpenFile(menuInfoFileName, os.O_RDWR|os.O_CREATE, 0666); err == nil {
				defer fi.Close()
				fi.Truncate(0)
				fi.Seek(0, 0)
				fi.Write(dataSave)
			} else {
				fmt.Println(menuInfoFileName, err)
			}
		}
	} else {
		fmt.Println(112)
	}
	reply["Cmd"] = "autoAddCurrentMenu"
	replyData, _ := json.Marshal(reply)
	w.Header().Set("Content-Type", "application/json;charset=UTF-8")
	w.Write(replyData)
}
